﻿using System;

namespace Domain
{
    public class Triangle
    {
        public Point A { get; private set; }
        public Point B { get; private set; }
        public Point C { get; private set; }

        public double AB { get { return _AB.GetLength(); } }
        public double BC { get { return _BC.GetLength(); } }
        public double CA { get { return _CA.GetLength(); } }

        public double Alpha { get { return _alpha.GetRadian(); } }
        public double Beta  { get { return _beta.GetRadian();  } }
        public double Gamma { get { return _gamma.GetRadian(); } }

        public double Perimeter { get { return CalculatePerimeter(); } }
        public double Square    { get { return CalculateSquare();    } }

        private readonly Edge _AB;
        private readonly Edge _BC;
        private readonly Edge _CA;

        private readonly Angle _alpha;
        private readonly Angle _beta;
        private readonly Angle _gamma;

        public Triangle(Point A, Point B, Point C)
        {
            this.A = A;
            this.B = B;
            this.C = C;
            _AB = new Edge(A, B);
            _BC = new Edge(B, C);
            _CA = new Edge(C, A);
            _alpha = new Angle(B, A, C);
            _beta  = new Angle(C, B, A);
            _gamma = new Angle(A, C, B);
        }
        public bool IsDegenerate()
        {
            var leftValue = (A.x - B.x) * C.y;
            var rightValue = (A.y - B.y) * C.x + (A.x * B.y - B.x * A.y);

            return DoubleComparator.AreEqual(leftValue, rightValue);
        }
        public bool IsEquilateral()
        {
            return DoubleComparator.AreEqual(AB, BC, CA);
        }
        public bool IsIsosceles()
        {
            var c = AB;
            var a = BC;
            var b = CA;

            var isABequal = DoubleComparator.AreEqual(a, b);
            var isBCequal = DoubleComparator.AreEqual(b, c);
            var isACequal = DoubleComparator.AreEqual(a, c);

            return isABequal || isBCequal || isACequal;
        }
        private double CalculatePerimeter()
        {
            var perimeter = 0.0;
            var c = AB;
            var a = BC;
            var b = CA;

            if (IsDegenerate())
            {
                if (A != B && B != C)
                {
                    perimeter = Math.Max(Math.Max(c, a), b);
                }
            }
            else
            {
                perimeter = c + a + b;
            }
            return perimeter;
        }
        private double CalculateSquare()
        {
            var square = 0.0;

            if (!IsDegenerate())
            {
                var p = 0.5*CalculatePerimeter();
                var c = AB;
                var a = BC;
                var b = CA;
                square = Math.Sqrt(p*(p - a)*(p - b)*(p - c));
            }
            return square;
        }
    }
}

